#include "stdafx.h"

#include <QSettings>

#include "Config.h"
#include "Utils.h"

//*********************************************************
//
//   ConfigData
//
//*********************************************************
ConfigData::ConfigData()
{
    strUsername.clear();
    arrPassword.clear();
    bRememberPassword = false;
    strServers = this->SERVER_ADDR;

    iHeartbeatTime = 60;//s
    iIfErrorLog = 1;
    strLogDir = "./t2log/";
    iIfSendRecvLog = 0;
    iMaxLogFileSize = 50;//MB
    iMaxLogFileCount = 5;

    iWriteData = 0;
    iIfReqInfoClipping = 0;

    iAutoReconnect = 0;
    iReconnectTimeout = 1000;//ms

    iLogLevel = LogLevel::Debug;

    //strInDb = this->IN_DB;
    //strOutDb = this->OUT_DB;
    iInDbMonitorInterval = this->MONITOR_INTERVAL;

    bQuickEntrust = false;
    bAutoMonitor = true;
}

void ConfigData::clone(const ConfigData& o)
{
    this->strUsername = o.strUsername;
    this->arrPassword = o.arrPassword;
    this->bRememberPassword = o.bRememberPassword;
    this->strServers = o.strServers;

    this->iHeartbeatTime = o.iHeartbeatTime;
    this->iIfErrorLog = o.iIfErrorLog;
    this->strLogDir = o.strLogDir;
    this->iIfSendRecvLog = o.iIfSendRecvLog;
    this->iMaxLogFileSize = o.iMaxLogFileSize;
    this->iMaxLogFileCount = o.iMaxLogFileCount;

    this->iWriteData = o.iWriteData;
    this->iIfReqInfoClipping = o.iIfReqInfoClipping;

    this->iAutoReconnect = o.iAutoReconnect;
    this->iReconnectTimeout = o.iReconnectTimeout;

    this->iLogLevel = o.iLogLevel;

    //this->strInDb = o.strInDb;
    //this->strOutDb = o.strOutDb;
    this->iInDbMonitorInterval = o.iInDbMonitorInterval;

    this->bQuickEntrust = o.bQuickEntrust;
    this->bAutoMonitor = o.bAutoMonitor;
}

ConfigData& ConfigData::operator = (const ConfigData& o)
{
    this->clone(o);
    return *this;
}
//*********************************************************
//
//   ConfigMgr
//
//*********************************************************
ConfigMgr* ConfigMgr::m_pInstance = nullptr;

ConfigMgr* ConfigMgr::getInstance()
{
    return m_pInstance;
}

ConfigMgr* ConfigMgr::newInstance(const QString& fileName)
{
    m_pInstance = new ConfigMgr(fileName);

    return m_pInstance;
}

void ConfigMgr::destoryInstance()
{
    SAFE_DELETE(m_pInstance);
}

ConfigMgr::ConfigMgr(const QString& fileName)
{
    m_pSettings = new QSettings(fileName, QSettings::IniFormat);
}

ConfigMgr::~ConfigMgr()
{
    delete m_pSettings;
    m_pSettings = nullptr;
}

void ConfigMgr::setGroupName(const QString& groupName)
{
    m_groupName = groupName;
}

void ConfigMgr::save(const QString& name, bool val)
{
    m_pSettings->beginGroup(m_groupName);
    m_pSettings->setValue(name, val);
    m_pSettings->endGroup();

    qDebug() << "Write to config file: " << m_pSettings->fileName() << ", name = " << name << ", value = " << val;
}

void ConfigMgr::save(const QString& name, qint16 val)
{
    save(name, (qint32)val);
}

void ConfigMgr::save(const QString& name, quint16 val)
{
    save(name, (quint32)val);
}

void ConfigMgr::save(const QString& name, qint32 val)
{
    save(name, (qint64)val);
}

void ConfigMgr::save(const QString& name, quint32 val)
{
    save(name, (quint64)val);
}

void ConfigMgr::save(const QString& name, qint64 val)
{
    m_pSettings->beginGroup(m_groupName);
    m_pSettings->setValue(name, val);
    m_pSettings->endGroup();

    qDebug() << "Write to config file: " << m_pSettings->fileName() << ", name = " << name << ", value = " << val;
}

void ConfigMgr::save(const QString& name, quint64 val)
{
    m_pSettings->beginGroup(m_groupName);
    m_pSettings->setValue(name, val);
    m_pSettings->endGroup();

    qDebug() << "Write to config file: " << m_pSettings->fileName() << ", name = " << name << ", value = " << val;
}

void ConfigMgr::save(const QString& name, const QString& val)
{
    m_pSettings->beginGroup(m_groupName);
    m_pSettings->setValue(name, val);
    m_pSettings->endGroup();

    qDebug() << "Write to config file: " << m_pSettings->fileName() << ", name = " << name << ", value = " << val;
}


void ConfigMgr::save(const QString& name, const QByteArray& val)
{
    m_pSettings->beginGroup(m_groupName);
    QString hexString = QString(val.toHex(' ')).toLatin1().data();
    m_pSettings->setValue(name, hexString);
    m_pSettings->endGroup();

    qDebug() << "Write to config file: " << m_pSettings->fileName() << ", name = " << name << ", value = " << hexString;
}

void ConfigMgr::load(const QString& name, bool& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toBool();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, qint16& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toInt();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, quint16& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toInt();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, qint32& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toInt();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, quint32& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toInt();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, qint64& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toLongLong();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, quint64& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toLongLong();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, QString& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        val = m_pSettings->value(key).toString();
        qDebug() << key << " : " << val;
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load(const QString& name, QByteArray& val)
{
    QString key = m_groupName + "/" + name;
    if (m_pSettings->contains(key))
    {
        QString strVal = m_pSettings->value(key).toString();
        qDebug() << key << " : " << strVal;
        val = QByteArray::fromHex(strVal.toLatin1().data());
    }
    else
    {
        qDebug() << "Can't find '" << key << "' in config file: " << m_pSettings->fileName();
    }
}

void ConfigMgr::load()
{
    QFile file(m_pSettings->fileName());
    if (!file.exists())
    {
        this->save();
        return;
    }

    setGroupName(CONFIG_ITEM::GROUP_CONNECTION);
    load(CONFIG_ITEM::USERNAME, m_data.strUsername);
    load(CONFIG_ITEM::PASSWORD, m_data.arrPassword);
    load(CONFIG_ITEM::REMEMBER_PASSWORD, m_data.bRememberPassword);
    load(CONFIG_ITEM::SERVERS, m_data.strServers);

    load(CONFIG_ITEM::HEARTBEAT_TIME, m_data.iHeartbeatTime);
    load(CONFIG_ITEM::IF_ERROR_LOG, m_data.iIfErrorLog);
    load(CONFIG_ITEM::LOGDIR, m_data.strLogDir);
    load(CONFIG_ITEM::IF_SENDRECV_LOG, m_data.iIfSendRecvLog);
    load(CONFIG_ITEM::MAX_LOG_FILE_SIZE, m_data.iMaxLogFileSize);
    load(CONFIG_ITEM::MAX_LOG_FILE_COUNT, m_data.iMaxLogFileCount);

    load(CONFIG_ITEM::WRITEDATA, m_data.iWriteData);
    load(CONFIG_ITEM::IF_REQINFO_CLIIPPING, m_data.iIfReqInfoClipping);

    load(CONFIG_ITEM::AUTO_RECONNECT, m_data.iAutoReconnect);
    load(CONFIG_ITEM::RECONNECT_TIMEOUT, m_data.iReconnectTimeout);

    setGroupName(CONFIG_ITEM::GROUP_LOG);
    load(CONFIG_ITEM::LOG_LEVEL, m_data.iLogLevel);

    setGroupName(CONFIG_ITEM::GROUP_INTERFACE);
    //load(CONFIG_ITEM::IN_DB, m_data.strInDb);
    //load(CONFIG_ITEM::OUT_DB, m_data.strOutDb);
    load(CONFIG_ITEM::IN_DB_MONITOR_INTERVAL, m_data.iInDbMonitorInterval);

    setGroupName(CONFIG_ITEM::GROUP_UI);
    load(CONFIG_ITEM::QUICK_ENTRUST, m_data.bQuickEntrust);
    load(CONFIG_ITEM::AUTO_MONITOR, m_data.bAutoMonitor);
}

void ConfigMgr::save()
{
    setGroupName(CONFIG_ITEM::GROUP_CONNECTION);
    save(CONFIG_ITEM::USERNAME, m_data.strUsername);
    save(CONFIG_ITEM::PASSWORD, m_data.arrPassword);
    save(CONFIG_ITEM::REMEMBER_PASSWORD, m_data.bRememberPassword);
    save(CONFIG_ITEM::SERVERS, m_data.strServers);

    //save(CONFIG_ITEM::HEARTBEAT_TIME, m_data.iHeartbeatTime);
    //save(CONFIG_ITEM::IF_ERROR_LOG, m_data.iIfErrorLog);
    //save(CONFIG_ITEM::LOGDIR, m_data.strLogDir);
    //save(CONFIG_ITEM::IF_SENDRECV_LOG, m_data.iIfSendRecvLog);
    //save(CONFIG_ITEM::MAX_LOG_FILE_SIZE, m_data.iMaxLogFileSize);
    //save(CONFIG_ITEM::MAX_LOG_FILE_COUNT, m_data.iMaxLogFileCount);

    //save(CONFIG_ITEM::WRITEDATA, m_data.iWriteData);
    //save(CONFIG_ITEM::IF_REQINFO_CLIIPPING, m_data.iIfReqInfoClipping);

    //save(CONFIG_ITEM::AUTO_RECONNECT, m_data.iAutoReconnect);
    //save(CONFIG_ITEM::RECONNECT_TIMEOUT, m_data.iReconnectTimeout);

    setGroupName(CONFIG_ITEM::GROUP_LOG);
    save(CONFIG_ITEM::LOG_LEVEL, m_data.iLogLevel);

    setGroupName(CONFIG_ITEM::GROUP_INTERFACE);
    //save(CONFIG_ITEM::IN_DB, m_data.strInDb);
    //save(CONFIG_ITEM::OUT_DB, m_data.strOutDb);
    save(CONFIG_ITEM::IN_DB_MONITOR_INTERVAL, m_data.iInDbMonitorInterval);

    setGroupName(CONFIG_ITEM::GROUP_UI);
    save(CONFIG_ITEM::QUICK_ENTRUST, m_data.bQuickEntrust);
    save(CONFIG_ITEM::AUTO_MONITOR, m_data.bAutoMonitor);
}

ConfigData& ConfigMgr::getData()
{
    return ConfigMgr::getInstance()->m_data;
}
